﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using org.iringtools.library;
using NHibernate.Cfg;
using System.Reflection;
using Ninject;
using NInjectTest;
using org.iringtools.utility;
using System.IO;
using org.iringug.iringtools.test;
using NHibernate.Mapping.Attributes;

namespace IRINGAdapter
{
  public class AdapterService
  {
    private string appPath;
    private IKernel kernel;
    private int appCount = 0;

    public AdapterService()
    {
      //appPath = AppDomain.CurrentDomain.BaseDirectory;
      appPath = @"C:\Development\VS08 Projects\IRINGAdapter\IRINGAdapter"; 
      kernel = new StandardKernel();
      //TODO: Load db repository and initialize appCount
    }

    private Dictionary<string, string> NHibernateSettings(Provider provider, string connectionString)
    {
      string connectionProvider = "NHibernate.Connection.DriverConnectionProvider";
      string connectionDriver = String.Empty;
      string factoryClass = "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle";
      string dialect = String.Empty;
      string showSql = "false";
      
      switch (provider)
      {
        case Provider.MySQL:
          connectionDriver = "NHibernate.Driver.MySqlDataDriver";
          dialect = "NHibernate.Dialect.MySQL5Dialect";
          break;

        case Provider.MSSQL:
          connectionDriver = "NHibernate.Driver.SqlClientDriver";
          dialect = "NHibernate.Dialect.MsSql2008Dialect";
          break;

        case Provider.Oracle:
          connectionDriver = "NHibernate.Driver.OracleClientDriver";
          dialect = "NHibernate.Dialect.Oracle10gDialect";          
          break;
      }

      Dictionary<string, string> settings = new Dictionary<string, string>()
      {
        { "connection.provider", connectionProvider },
        { "connection.driver_class", connectionDriver },
        { "connection.connection_string", connectionString },
        { "proxyfactory.factory_class", factoryClass },
        { "dialect", dialect },
        { "show_sql", showSql }
      };

      return settings;
    }

    public string PostDatabaseDictionary(DatabaseDictionary dbDictionary)
    {
      try
      {
        // Generate entities
        EntityGenerator entityGenerator = new EntityGenerator();
        entityGenerator.Generate(dbDictionary, "v3.5", "org.iringug.iringtools.test", null, appPath);

        // Bind data layer to kernel
        Configuration config = new Configuration();
        Dictionary<string, string> props = NHibernateSettings(dbDictionary.provider, dbDictionary.connectionString);
        foreach (var pair in props)
        {
          config.Properties.Add(pair);
        }
        //TODO: make sure old mappings are not re-processed
        MemoryStream stream = HbmSerializer.Default.Serialize(Assembly.GetExecutingAssembly());
        Utility.WriteStream(stream, @"c:\temp\test2.xml");
        config.AddInputStream(stream);
        stream.Close();

        DataLayerProvider dataLayerProvider = new DataLayerProvider();
        dataLayerProvider.Configuration = config;

        appCount++;
        string appName = "app" + appCount;
        kernel.Bind<IDataLayer>().ToProvider(dataLayerProvider).InRequestScope().Named(appName);

        // Write dbDictionary to disk
        Utility.Write<DatabaseDictionary>(dbDictionary, appPath + @"\Repository\" + appName + ".xml", true);

        return appName;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    public List<T> GetList<T>(string appName)
    {
      try
      {
        IDataLayer dataLayer = kernel.Get<IDataLayer>(appName);
        return dataLayer.GetList<T>();
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }
  }
}
